#ifndef ACO_HPP
#define ACO_HPP

#include "graph.hpp"
#include "palette.hpp"
#include "ant.hpp"
#include "end_condition.hpp"
#include "objective_function.hpp"
#include "stopwatch.hpp"
#include <vector>

class aco_c : public objective_function_i
{        
        typedef std::vector < ant_c * >         ants_v;
        typedef double                          rcp_result;

        graph_c *               graph;
        palette_c *             palette;
        ants_v *                ants;
        ant_c *                 best_ant;
        rcp_result              best_ant_result;
        double                  r_modifier;
        double                  k_modifier;
        long                    k_bound;
        long                    r_bound;
        end_condition_i &       end_condition;
        stopwatch_c             stopwatch;

        rcp_result      calculate_ant_result    ( const ant_c & ant ) const;    // TODO: move this method to ant_c
        void            update_pheromone_paths  ( void ) const;

public:
        ~aco_c ( void );
        aco_c ( end_condition_i & end_condition );

        void    load_dimacs_graph       ( const char * file_path );
        void    flush_dimacs_solution   ( const char * file_path );
        void    set_r_modifier          ( double r_modifier );
        void    set_k_modifier          ( double k_modifier );
        void    set_k_bound             ( long k_bound );
        void    set_r_bound             ( long r_bound );
        void    run                     ( void );
        long    get_running_time_ms     ( void ) const;
        
        virtual double evaluate         ( void ) const;
};

#endif

